package com.yupi.mianshiya.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yupi.mianshiya.common.BaseResponse;
import com.yupi.mianshiya.common.ErrorCode;
import com.yupi.mianshiya.common.ResultUtils;
import com.yupi.mianshiya.exception.ThrowUtils;
import com.yupi.mianshiya.model.dto.paper.PaperQueryRequest;
import com.yupi.mianshiya.model.entity.Paper;
import com.yupi.mianshiya.model.entity.QuestionBank;
import com.yupi.mianshiya.model.entity.User;
import com.yupi.mianshiya.model.vo.PaperVO;
import com.yupi.mianshiya.service.PaperService;
import com.yupi.mianshiya.service.QuestionBankService;
import com.yupi.mianshiya.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Api(tags = "题库题目小练习接口")
@RestController
@RequestMapping("/paper")
@Slf4j
public class PaperController {
    @Resource
    private PaperService paperService;

    @Resource
    private UserService userService;

    @Resource
    private QuestionBankService questionBankService;


    @ApiOperation("添加题目小练习")
    @PostMapping("/add")
    public BaseResponse<Boolean> addPaper(@RequestBody Paper paper, HttpServletRequest request) {
        boolean admin = userService.isAdmin(request);
        ThrowUtils.throwIf(!admin, ErrorCode.NO_AUTH_ERROR);

        //校验
        ThrowUtils.throwIf(paper == null, ErrorCode.PARAMS_ERROR);
        ThrowUtils.throwIf(paper.getContent() == null, ErrorCode.PARAMS_ERROR);
        ThrowUtils.throwIf(paper.getCorrectAnswer() == null, ErrorCode.PARAMS_ERROR);
        ThrowUtils.throwIf(paper.getUserId() == null, ErrorCode.PARAMS_ERROR);

        //添加
        boolean save = paperService.save(paper);
        ThrowUtils.throwIf(!save, ErrorCode.OPERATION_ERROR, "添加题目小练习失败");
        return ResultUtils.success(true);

    }

    @ApiOperation("删除题目小练习")
    @DeleteMapping("/delete")
    public BaseResponse<Boolean> deletePaper(@RequestParam("id") Long id, HttpServletRequest request) {
        boolean admin = userService.isAdmin(request);
        ThrowUtils.throwIf(!admin, ErrorCode.NO_AUTH_ERROR);

        //删除
        boolean b = paperService.removeById(id);
        ThrowUtils.throwIf(!b, ErrorCode.OPERATION_ERROR, "删除题目小练习失败");
        return ResultUtils.success(true);
    }

    @ApiOperation("更新题目小练习")
    @PostMapping("/update")
    public BaseResponse<Boolean> updatePaper(@RequestBody Paper paper, HttpServletRequest request) {
        boolean admin = userService.isAdmin(request);
        ThrowUtils.throwIf(!admin, ErrorCode.NO_AUTH_ERROR);

        //校验
        ThrowUtils.throwIf(paper == null, ErrorCode.PARAMS_ERROR);
        ThrowUtils.throwIf(paper.getId() == null, ErrorCode.PARAMS_ERROR);
        ThrowUtils.throwIf(paper.getContent() == null, ErrorCode.PARAMS_ERROR);
        ThrowUtils.throwIf(paper.getCorrectAnswer() == null, ErrorCode.PARAMS_ERROR);


        //更新
        boolean b = paperService.updateById(paper);
        ThrowUtils.throwIf(!b, ErrorCode.OPERATION_ERROR, "更新题目小练习失败");
        return ResultUtils.success(true);
    }

    @ApiOperation("根据id获取题目小练习")
    @GetMapping("/get")
    public BaseResponse<Paper> getPaper(@RequestParam("id") Long id, HttpServletRequest request) {
        boolean admin = userService.isAdmin(request);
        ThrowUtils.throwIf(!admin, ErrorCode.NO_AUTH_ERROR);

        //获取试卷
        Paper paper = paperService.getById(id);
        ThrowUtils.throwIf(paper == null, ErrorCode.NOT_FOUND_ERROR, "题目小练习不存在");
        return ResultUtils.success(paper);
    }

    @ApiOperation("随机获得几道题")
    @GetMapping("/random")
    public BaseResponse<List<Paper>> getPaperList(@RequestParam(value = "limit", defaultValue = "5") int limit, @RequestParam(value = "questionbankid") long questionbankid, HttpServletRequest request) {
        userService.getLoginUser(request);
        List<Paper> list = paperService.listRandom(limit, questionbankid);
        return ResultUtils.success(list);

    }

    @ApiOperation("管理员分页获取题目小练习")
    @GetMapping("/list")
    public BaseResponse<Page<PaperVO>> listPaper(PaperQueryRequest paperQueryRequest, HttpServletRequest request) {
        boolean admin = userService.isAdmin(request);
        ThrowUtils.throwIf(!admin, ErrorCode.NO_AUTH_ERROR);
        int current = paperQueryRequest.getCurrent();
        int size = paperQueryRequest.getPageSize();
        //分页获取试卷
        QueryWrapper<Paper> queryWrapper = paperService.getQueryWrapper(paperQueryRequest);
        Page<Paper> paperpage = paperService.page(new Page<>(current, size), queryWrapper);

        //  收集所有 questionBankId
        Set<Long> bankIds = paperpage.getRecords()
                .stream()
                .map(Paper::getQuestionbankid)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());

        //  批量查题库名称
        Map<Long, String> bankNameMap;
        if (!bankIds.isEmpty()) {
            List<QuestionBank> banks = questionBankService.listByIds(bankIds);
            bankNameMap = banks.stream()
                    .collect(Collectors.toMap(QuestionBank::getId, QuestionBank::getTitle));
        } else {
            bankNameMap = new HashMap<>();
        }


        // 4. 转换 VO 并填充名称
        List<PaperVO> voList = paperpage.getRecords()
                .stream()
                .map(p -> {
                    PaperVO v = new PaperVO();
                    BeanUtils.copyProperties(p, v);
                    v.setQuestionname(bankNameMap.get(p.getQuestionbankid()));
                    return v;
                })
                .collect(Collectors.toList());

        // 5. 组装 Page
        Page<PaperVO> voPage = new Page<>(paperpage.getCurrent(), paperpage.getSize(), paperpage.getTotal());
        voPage.setRecords(voList);

        return ResultUtils.success(voPage);

        }


    }
